		TITLE	OUTLIB - Copyright (C) SLR Systems 1994

		INCLUDE	MACROS
if	V5
		INCLUDE	SYMBOLS
		INCLUDE	SEGMSYMS
		INCLUDE	IO_STRUC

		PUBLIC	OUTPUT_LIB


		.DATA

		EXTERNDEF	TEMP_RECORD:BYTE,EXPORTED_TXT:BYTE,MODULE_NAME:BYTE

		EXTERNDEF	IMP_DEVICE:DWORD,IMPLIB_FILE_GINDEX:DWORD,IMPLIB_PAGESIZE:DWORD
		EXTERNDEF	ENTRYNAMES_TOTAL_LENGTH:DWORD,FIRST_ENTRYNAME_GINDEX:DWORD,IMPLIB_PAGEBITS:DWORD

		EXTERNDEF	ENTRYNAME_GARRAY:STD_PTR_S,SYMBOL_GARRAY:STD_PTR_S

		EXTERNDEF	IMP_OUTALL:DWORD,IMPLIB_COFF_FILE_GINDEX:DWORD


		.CODE	PASS2_TEXT

		EXTERNDEF	IMP_INIT:PROC,_flush_trunc_close:proc,CASE_STRING_COMPARE_HARD:PROC,ERR_ABORT:PROC
		EXTERNDEF	BUILD_DIRECTORY:PROC,WRITE_DIRECTORY:PROC,MOVE_DSSIAX_TO_NEWOMF:PROC,MOVE_ASCIZ_ESI_EDI:PROC
		EXTERNDEF       MAKE_COFF_IMPLIB:PROC

		EXTERNDEF	PAGESIZE_ERR:ABS,EXPORTED_TXT_LEN:ABS,BAD_PAGESIZE_ERR:ABS


OUTLIB_VARS	STRUC

INT_SYMBOL_LENGTH_BP	DD	?
INT_SYMBOL_TEXT_BP	DB	SYMBOL_TEXT_SIZE DUP(?)
EXT_SYMBOL_LENGTH_BP	DD	?
EXT_SYMBOL_TEXT_BP	DB	SYMBOL_TEXT_SIZE DUP(?)
ENTS_BP			ENT_STRUCT <>
RECORD_OFFSET_BP	DD	?
ENTRY_OFFSET_BP		DD	?
ENTRY_LENGTH_BP		DD	?

OUTLIB_VARS	ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE OUTLIB_VARS].(X&_BP))

	ENDM


FIX	INT_SYMBOL_LENGTH
FIX	INT_SYMBOL_TEXT
FIX	EXT_SYMBOL_LENGTH
FIX	EXT_SYMBOL_TEXT
FIX	ENTS
FIX	RECORD_OFFSET
FIX	ENTRY_OFFSET
FIX	ENTRY_LENGTH


OUTPUT_LIB	PROC
		;
		;IF REQUESTED, OUTPUT A .LIB FILE TO BE INCLUDED WHEN LINKING TO THIS GUY
		;
		GETT	CL,IMPLIB_FLAG
		MOV	EAX,IMPLIB_FILE_GINDEX

		OR	CL,CL
		JZ	L01$
		;
		;OPEN .LIB FILE
		;
		TEST	EAX,EAX
		JNZ	L02$

L01$:
		;
		;IF REQUESTED, OUTPUT A .LIB FILE TO BE INCLUDED WHEN LINKING TO THIS GUY
		;
		BITT	OUTPUT_PE
		JZ	L9$

		GETT	CL,IMPLIB_COFF_FLAG
		MOV	EAX,IMPLIB_COFF_FILE_GINDEX

		OR	CL,CL
		JZ	L9$
		;
		;GENERATE .LIB FILE
		;
		TEST	EAX,EAX
		JZ	L9$

		CALL    MAKE_COFF_IMPLIB

		RET



L02$:
                PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
		SUB	ESP,SIZE OUTLIB_VARS - SYMBOL_TEXT_SIZE*2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
                SUB	ESP,SYMBOL_TEXT_SIZE/2 - 4
                PUSH	EBP
		ASSUME	EBP:PTR OUTLIB_VARS
		;
		;OPEN .LIB FILE
		;
		CALL	IMP_INIT
		;
		;SEND 'LIBHEADER' RECORD
		;
		MOV	IMP_DEVICE,EAX
		XOR	ECX,ECX

		MOV	EAX,IMPLIB_PAGESIZE
		DEC	ECX
L1$:
		INC	ECX
		SHR	EAX,1

		JNC	L1$

		JNZ	PAGESIZE_ERROR

		MOV	IMPLIB_PAGEBITS,ECX
		CMP	ECX,9

		MOV	EDI,OFF TEMP_RECORD
		JA	PAGESIZE_ERROR

		XOR	EAX,EAX
		MOV	ECX,IMPLIB_PAGESIZE

		MOV	EDX,EDI
		PUSH	ECX

		REP	STOSB

		POP	ECX
		MOV	EAX,EDX

		CALL	IMP_OUTALL
		;
		;OUTPUT EACH ENTRYNAME THAT IS DEFINED
		;
		MOV	EBX,FIRST_ENTRYNAME_GINDEX
		JMP	L8$

PAGESIZE_ERROR:
		MOV	AX,BAD_PAGESIZE_ERR
		CALL	ERR_ABORT

L9$:
		RET


L77$:
		OR	[EBX]._ENT_FLAGS,MASK ENT_PRIVATE
		JMP	L79$

L2$:
		CONVERT	EBX,EBX,ENTRYNAME_GARRAY
		ASSUME	EBX:PTR ENT_STRUCT
		;
		;OUTPUT EXPORTED NAME
		;
		MOV	AL,[EBX]._ENT_FLAGS
		LEA	EDI,ENTS

		TEST	AL,MASK ENT_UNDEFINED+MASK ENT_PRIVATE
		JNZ	L79$

		MOV	ESI,EBX		;COPY THIS ENTRY TO LOCAL STORAGE
		MOV	ECX,ENT_STRUCT._ENT_TEXT/4

		REP	MOVSD

		LEA	EDI,EXT_SYMBOL_TEXT
		CALL	MOVE_ASCIZ_ESI_EDI

		MOV	EAX,EDI
		LEA	EDX,EXT_SYMBOL_TEXT

		XOR	ECX,ECX
		SUB	EAX,EDX

		MOV	DPTR [EDI],ECX
		MOV	EXT_SYMBOL_LENGTH,EAX

		MOV	ECX,DPTR EXT_SYMBOL_TEXT
		;
		;CHECK FOR IGNORING WEP AND ___EXPORTEDSTUB
		;
		CMP	EAX,3			;MAYBE WEP?
		JZ	L24$

		CMP	EAX,EXPORTED_TXT_LEN	;MAYBE EXPORTEDSTUB?
		JNZ	L29$

		CMP	EDX,'E___'
		JZ	L23$

		CMP	EDX,'e___'
		JNZ	L29$
L23$:
		MOV	ESI,OFF EXPORTED_TXT
		LEA	EDI,EXT_SYMBOL_TEXT

		MOV	ECX,EAX
		CALL	CASE_STRING_COMPARE_HARD

		JNZ	L29$

		JMP	L77$

L24$:
		CMP	ECX,'PEW'
		JZ	L77$
L29$:
		;
		;NOW DEFINE INTERNAL NAME
		;
		LEA	ESI,EXT_SYMBOL_TEXT
		MOV	AL,[EBX]._ENT_FLAGS

		TEST	AL,MASK ENT_USE_EXTNAM
		JNZ	L35$

		MOV	ESI,[EBX]._ENT_INTERNAL_NAME_GINDEX

		CONVERT	ESI,ESI,SYMBOL_GARRAY

		ADD	ESI,SYMBOL_STRUCT._S_NAME_TEXT
L35$:
		LEA	EDI,INT_SYMBOL_TEXT
		CALL	MOVE_ASCIZ_ESI_EDI

		MOV	EAX,EDI
		LEA	EDX,INT_SYMBOL_TEXT

		XOR	ECX,ECX
		SUB	EAX,EDX

		MOV	DPTR [EDI],ECX
		MOV	INT_SYMBOL_LENGTH,EAX
		;
		;EBX IS ENTRY
		;
		MOV	EAX,EBX
		CALL	HASH_EXPORT

		MOV	EAX,EXT_SYMBOL_LENGTH
		MOV	ECX,ENTRYNAMES_TOTAL_LENGTH

		ADD	EAX,4

		AND	AL,0FEH

		ADD	EAX,ECX

		MOV	ENTRYNAMES_TOTAL_LENGTH,EAX
		CALL	FLUSH_EXPORT

		MOV	EAX,OFF TEMP_RECORD
		MOV	ECX,EDI

		SUB	ECX,EAX
		CALL	IMP_OUTALL
L79$:
		MOV	EBX,[EBX]._ENT_NEXT_ENT_GINDEX
L8$:
		TEST	EBX,EBX
		JNZ	L2$
		;
		;BUILD AND FLUSH DICTIONARY - CLOSE FILE
		;
		CALL	BUILD_DIRECTORY

		CALL	WRITE_DIRECTORY

		MOV	ESP,EBP

		POPM	EBX,ESI,EDI,EBP

		RET

OUTPUT_LIB	ENDP


HASH_EXPORT	PROC	NEAR
		;
		;
		;
		MOV	EDX,IMP_DEVICE
		MOV	ECX,IMPLIB_PAGEBITS

		MOV	EAX,[EDX].MYO_STRUCT.MYO_BYTE_OFFSET

		SHR	EAX,CL				;USUALLY 4

		CMP	EAX,64K
		JAE	L5$

		MOV	[EBX]._ENT_LIBRARY_PAGE,EAX
		MOV	ENTRY_OFFSET,EBX

		MOV	EAX,INT_SYMBOL_LENGTH
		LEA	ESI,INT_SYMBOL_TEXT-1

		MOV	ENTRY_LENGTH,EAX
		MOV	EDI,EAX		;SYMBOL LENGTH

		MOV	[ESI],AL	;STORE FOR HASHING
;		OR	AH,AH
;		JZ	0$
;		DEC	SI
;		MOV	AX,0FFH
;		MOV	ES:[SI],AX	;WALTER HASHES BOTH OF THESE
;0$:
		;
		;EDI IS SYMBOL LENGTH
		;
		XOR	EDX,EDX		;CALC_START IS IN 	EDX

		XOR	ECX,ECX		;CALC_DELTA_ENTRY IN	ECX
		MOV	AL,[ESI]

		INC	ESI
		OR	AL,20H

		MOV	DL,AL
		MOV	CL,AL

		DEC	EDI
		JZ	L2$
L1$:
		ROL	DX,2
		MOV	AL,[ESI]

		ROR	CX,2
		OR	AL,20H

		INC	ESI
		XOR	DL,AL

		XOR	CL,AL
		DEC	EDI

		JNZ	L1$
L2$:
		MOV	EAX,ECX
		MOV	[EBX]._ENT_START_BLOCK,EDX

		XOR	EDX,EDX
		MOV	ECX,37

		DIV	CX

		MOV	[EBX]._ENT_DELTA_ENTRY,DL	;ENTRY_DELTA_HASH
		OR	DL,DL

		MOV	EDI,ENTRY_LENGTH
		JZ	L8$
L89$:
		;
		;NOW, GO BACKWARDS, DOING THE SAME THING
		;
		MOV	AL,[ESI]
		XOR	EDX,EDX		;CALC_DELTA_START

		XOR	ECX,ECX		;CALC_ENTRY
		OR	AL,20H

		DEC	ESI
		MOV	DL,AL

		MOV	CL,AL
		DEC	EDI

		JZ	L4$
L3$:
		ROL	DX,2
		MOV	AL,[ESI]

		ROR	CX,2
		OR	AL,20H

		DEC	ESI
		XOR	DL,AL

		XOR	CL,AL
		DEC	EDI

		JNZ	L3$
L4$:
		MOV	EAX,ECX
		MOV	[EBX]._ENT_DELTA_BLOCK,EDX	;STORE DELTA_START HASH (16-BITS)

		XOR	EDX,EDX
		MOV	ECX,37		;CALC ENTRY #

		DIV	CX

		MOV	[EBX]._ENT_START_ENTRY,DL
		MOV	EAX,ENTRY_LENGTH

		OR	ECX,ECX
		MOV	INT_SYMBOL_LENGTH,EAX		;RESTORE, WE MUNGED IT

		RET

L5$:
		MOV	AX,PAGESIZE_ERR
		CALL	ERR_ABORT

L8$:
		INC	[EBX]._ENT_DELTA_ENTRY	;ONCE IN 37
		JMP	L89$

HASH_EXPORT	ENDP


FLUSH_EXPORT	PROC	NEAR
		;
		;
		;01	;1 MEANS IMPORT, 2 MEANS EXPORT (FROM C5.1????)
		;01	;1 MEANS ORDINAL, 0 MEANS BY NAME
		;STRING	;THIS IS THE SYMBOL NAME
		;STRING	;THIS IS THE LIBRARY NAME
		;IF ORDINAL, THIS IS THE ORDINAL #
		;
		;FIRST, DO THEADR RECORD, USE SYMBOL NAME AS THEADR NAME
		;
		MOV	EDI,OFF TEMP_RECORD
		MOV	AL,80H			;THEADR

		MOV	RECORD_OFFSET,EDI
		LEA	ESI,EXT_SYMBOL_TEXT

		MOV	[EDI],AL
		MOV	EAX,EXT_SYMBOL_LENGTH

		ADD	EDI,3
		CALL	MOVE_DSSIAX_TO_NEWOMF

		LEA	EAX,[EDI+1]
		INC	EDI

		SUB	EAX,OFF TEMP_RECORD+3

		MOV	WPTR TEMP_RECORD+1,AX
		CALL	CHECKSUM_RECORD		;SET CHECKSUM

		MOV	RECORD_OFFSET,EDI
		;
		;NOW BUILD COMENT RECORD
		;
		MOV	BPTR [EDI],88H		;COMENT RECORD
		MOV	EAX,160*256

		MOV	[EDI+3],AL
		MOV	AL,1

		MOV	[EDI+4],AH
		MOV	CL,ENTS._ENT_FLAGS

		MOV	[EDI+5],AL
		ADD	EDI,6

		AND	CL,MASK ENT_ORD_SPECIFIED
		JNZ	L1$

		DEC	EAX			;0 IF BY NAME
L1$:
		LEA	ESI,INT_SYMBOL_TEXT	;FIRST IS INTERNAL NAME

		MOV	[EDI],AL
		INC	EDI

		MOV	EAX,[ESI-4]
		CALL	MOVE_DSSIAX_TO_NEWOMF	;MOVE INTERNAL NAME

		MOV	ESI,OFF MODULE_NAME+4

		MOV	EAX,[ESI-4]
		CALL	MOVE_DSSIAX_TO_NEWOMF	;MOVE MODULE NAME
		;
		;IF BYORD, OUTPUT ORDINAL, ELSE EXT_SYMBOL_TEXT
		;
		MOV	AL,ENTS._ENT_FLAGS
		MOV	ECX,ENTS._ENT_ORD

		TEST	AL,MASK ENT_ORD_SPECIFIED
		JNZ	L3$
		;
		;BY NAME, OUTPUT EXT_SYMBOL_TEXT IF IT DIFFERS FROM INT_SYMBOL
		;
		MOV	ECX,INT_SYMBOL_LENGTH
		MOV	EAX,EXT_SYMBOL_LENGTH

		CMP	ECX,EAX
		JNZ	L16$

		SHR	ECX,2
		LEA	ESI,EXT_SYMBOL_TEXT

		PUSH	EDI
		LEA	EDI,INT_SYMBOL_TEXT

		INC	ECX
		XOR	EAX,EAX

		REPE	CMPSD

		POP	EDI
		JZ	L16$
L15$:
		MOV	EAX,EXT_SYMBOL_LENGTH
L16$:
		LEA	ESI,EXT_SYMBOL_TEXT
		CALL	MOVE_DSSIAX_TO_NEWOMF

		JMP	L4$

L3$:
		MOV	[EDI],CX
		ADD	EDI,2
L4$:
		INC	EDI
L2$:
		PUSH	EDI
		MOV	ESI,RECORD_OFFSET

		SUB	EDI,ESI

		SUB	EDI,3

		MOV	WPTR [ESI+1],DI
		CALL	CHECKSUM_RECORD
		;
		;NOW DO SIMPLE MODEND
		;
		POP	EDI
		MOV	ESI,OFF MODEND_RECORD

		MOV	ECX,SIZEOF MODEND_RECORD

		REP	MOVSB
		;
		;THEN, ALIGN TO PAGESIZE BOUNDARY
		;
		MOV	EDX,IMPLIB_PAGESIZE
		MOV	ECX,OFF TEMP_RECORD

		DEC	EDX
		SUB	ECX,EDI

		XOR	EAX,EAX
		AND	ECX,EDX

		REP	STOSB

		RET

FLUSH_EXPORT	ENDP


CHECKSUM_RECORD	PROC	NEAR
		;
		;RECALC. THE CHECKSUM FROM THE DATA AND COMPARE TO THE
		;CHECKSUM READ IN FROM BUFFER
		;
		PUSH	ESI
		MOV	ESI,RECORD_OFFSET

		XOR	ECX,ECX
		XOR	EDX,EDX

		MOV	CL,[ESI+1]
		PUSH	EBX

		MOV	CH,[ESI+2]

		ADD	ECX,2
		;
		;DS:SI IS START OF RECORD
		;CX IS RECORD LENGTH
		;
		;
		;CALCULATE CHECKSUM
		;
		PUSH	ECX

		SHR	ECX,2		;DIVIDE LENGTH BY 4
		JZ	SMALL		;JUMP IF LESS THAN 4 BYTES
LOW1:
		MOV	AL,[ESI]

		MOV	BL,[ESI+1]
		ADD	DL,AL

		MOV	AL,[ESI+2]
		ADD	DL,BL

		MOV	BL,[ESI+3]
		ADD	DL,AL

		ADD	ESI,4
		ADD	DL,BL

		DEC	ECX
		JNZ	LOW1
SMALL:
		POP	ECX		;NOW SLOW LOOP FOR MOD 8 BYTES

		AND	ECX,3
		JZ	AQW
LOOPT:
		ADD	DL,[ESI]
		INC	ESI

		DEC	ECX
		JNZ	LOOPT
AQW:
		NEG	DL		;DL IS DESIRED CHECKSUM

		POP	EBX
		MOV	[ESI],DL

		POP	ESI

		RET

CHECKSUM_RECORD	ENDP


		.CONST

MODEND_RECORD	DB	8AH,2,0,1,73H

endif

		END

